/* The example shows
  1. How to set a server program to listen to certain port, and wait on server socket.
  2. When a client requests a connection, the server creates a socket linking to client
     and sends out a menu with 3 choices.
  3. If a client select one of the first two choices, a java program is sending out.
     If the last choice is selected, the the connection is disconnected.
  4. How to use thread to handle multiple connection requestion.
*/
import java.io.* ;
import java.net.* ;

public class ServerSocketTest {
   public static void main( String arg[] ) {
	int connCount = 1;
	try {
		// --------------------------------------------------------------
		// 8900 is a special port number that allows server and client 
		// programs run on the same machine. TCP/IP must be installed
		// even if client and server running on the same machine.
		// --------------------------------------------------------------
	     	ServerSocket sv = new ServerSocket(8900) ;
		while ( true ) {
		   System.out.println("Waiting for client to connect ...");
		   Socket connSK = sv.accept() ;
		   System.out.println("A client's request for connection accepted ...");
		   System.out.println("Connection " + connCount ) ;
		   ThreadedConnectionHandler t =
			new ThreadedConnectionHandler( connSK, connCount ) ;
		   t.start() ; connCount++ ; }
	} catch ( Exception e ) { System.out.println( e.toString ()) ; }

    }

}

class ThreadedConnectionHandler extends Thread {

   Socket sk = null ;
   int    curConnect = 0 ;
   String str = null ;
   
   public ThreadedConnectionHandler ( Socket s, int k ) {
	sk = s;  curConnect = k ; 
	System.out.println("Connection# "+k) ; }

   public void run() {
      try {
	BufferedReader in = new BufferedReader ( new InputStreamReader(sk.getInputStream())) ;
	// Combine socket and stream op.
	PrintWriter out = new PrintWriter(sk.getOutputStream(),true) ;
	boolean stop = false ;
	int k ;
	while ( ! stop ) {
		System.out.println("Before sending menu out");
		out.println("\r\n\r");
		out.println("\t\t\t=========================\r");
		out.println("\t\t\t1. Get the server program\r") ;
		out.println("\t\t\t2. Get the client program\r") ;
		out.println("\t\t\t3. Close Connnection\r") ;
		out.println("\t\t\t=========================\r");
		out.print("\t\t\t  Your choice: ") ;
		out.flush() ;
		System.out.println("Menu out and waiting for client request...");
		str = null ;
		str = in.readLine() ;
		out.println("\r") ; out.flush() ;
		
		if ( str != null ) {
			k = Integer.parseInt(str);	
			switch ( k ) {
				case 1: displayFileThroughSocket("ServerSocketTest.java", out) ;
					out.flush(); break;
				case 2: displayFileThroughSocket("ClientSocketTest.java", out) ;
					out.flush(); break;
				case 3: out.println("Bye-Bye"); stop = true; break;
				default: stop = true;
			}
		}

	}
	System.out.println("A connection " + curConnect + " is closed.");
	sk.close() ;
      } catch( Exception e ) { e.toString() ; }
   }

   void displayFileThroughSocket(String fileName, PrintWriter out) {

        try {	BufferedReader fin = new BufferedReader
			(new FileReader (fileName));
		String s = null, strLong = "";
		while ( (s = fin.readLine()) != null) {
			strLong +=  s + "\r"; }
		out.print(strLong) ;
		out.flush() ;
		fin.close();
	}
        catch (java.io.IOException e) { e.toString() ; }
   }
   
}
